package com.common.sdk.net.download.db;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue;

import com.android.sohu.sdk.common.toolbox.ToastUtils;
import com.common.sdk.net.download.callback.CallbackObservable;
import com.common.sdk.net.download.callback.error.CallbackEnum;
import com.common.sdk.net.download.callback.error.DownloadState;
import com.common.sdk.net.download.request.model.AbsDownloadInfo;
import com.common.sdk.net.download.request.model.DownloadInfo;
import com.common.sdk.net.download.util.DownloadFilePathUtils;
import com.common.sdk.net.download.util.DownloadInfoComparatorUtils;
import com.common.sdk.net.download.util.DownloadLog;

public class ControlCacheAndDb {

    /**已经添加过*/
    public static final long ADD_ALREADY_ADD = -100;
    /**添加失败*/
    public static final long ADD_FAILED = -1;

    private static BlockingQueue<DownloadInfo> downloadWaitQueue;
    private static Hashtable<String, DownloadInfo> downloadInfoTable;

    /**
     * 获获取所有下载信息
     * @return
     */
    public static List<DownloadInfo> getAllDownloadList() {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            List<DownloadInfo> list = new ArrayList<DownloadInfo>();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.getType() != AbsDownloadInfo.OTHER_TYPE) {
                        list.add(downloadInfo);
                    }
                }
                Collections.sort(list, new DownloadInfoComparatorUtils());
                return list;
            }
            return null;
        }
    }

    /**
     * 获取下载列表 包括下载中。下载暂停。下载停止，clone 出来的。不能操作
     * @return
     */
    public static List<DownloadInfo> getDownloadingList() {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            List<DownloadInfo> list = new ArrayList<DownloadInfo>();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.isWaitDownload() || downloadInfo.isStartDownload()
                            || downloadInfo.isPauseDownload() || downloadInfo.isStopDownload()) {
                        if (downloadInfo.getType() != AbsDownloadInfo.OTHER_TYPE) {
                            list.add(downloadInfo);
                        }
                    }
                }
                Collections.sort(list, new DownloadInfoComparatorUtils());
                return list;
            }
            return null;
        }
    }

    /**
     * 获取下载完成列表
     * @return
     */
    public static List<DownloadInfo> getDownloadedList() {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            List<DownloadInfo> list = new ArrayList<DownloadInfo>();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.isFinishDownload()) {
                        if (downloadInfo.getType() != AbsDownloadInfo.OTHER_TYPE) {
                            list.add(downloadInfo);
                        }
                    }
                }
                Collections.sort(list, new DownloadInfoComparatorUtils());
                return list;
            }
            return null;
        }
    }

    /**
     * 获取除apk的下载列表
     * @return
     */
    public static HashMap<String, DownloadInfo> getDownloadGeneral() {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            HashMap<String, DownloadInfo> mapGeneral = new HashMap<String, DownloadInfo>();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.getType() == AbsDownloadInfo.OTHER_TYPE) {
                        mapGeneral.put(downloadInfo.getDownloadPath(), downloadInfo);
                    }
                }
            }
            return mapGeneral;
        }
    }

    /**
     * 重新启动所有失败任务
     * @param downloadWaitQueue
     */
    public static void restartAllStopTasks(BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.isStopDownload()) {
                        list.add(downloadInfo);
                        addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                    }
                }
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WAIT_START_DOWNLOAD_LIST, list);
            }
        }
    }

    /**
     * 重新启动所有因SD空间不足的失败任务
     * @param downloadWaitQueue
     */
    public static void restartAllStopTasks(boolean isSdEnableDownload, BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.isStopDownload()) {
                        if (isSdEnableDownload) {
                            downloadInfo.enableDownload();
                        } else {
                            downloadInfo.unEnableDownload();
                        }
                        list.add(downloadInfo);
                        addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                    }
                }
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WAIT_START_DOWNLOAD_LIST, list);
            }
        }
    }

    /**
     * 
     * @param downloadWaitQueue
     */
    public static void restartAllPauseTasks(BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            HashMap<String, DownloadInfo> map = CacheDatabase.cloneCanterMap();
            if (!map.isEmpty()) {
                Iterator<Entry<String, DownloadInfo>> it = map.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, DownloadInfo> entry = it.next();
                    DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                    if (downloadInfo.isPauseDownload()) {
                        list.add(downloadInfo);
                        addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                    }
                }
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WAIT_START_DOWNLOAD_LIST, list);
            }
        }
    }

    /**
     * 重新启动所有任务
     * @param downloadWaitQueue
     */
    public static void restartAllTasks(BlockingQueue<DownloadInfo> downloadWaitQueue) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            HashMap<String, DownloadInfo> canterMap = CacheDatabase.getCanterMap();

            List<HashMap.Entry<String, DownloadInfo>> listCollections = listCollections(canterMap);
            Iterator<Entry<String, DownloadInfo>> iterator = listCollections.iterator();
            // Set<Entry<String, DownloadInfo>> set = canterMap.entrySet();
            // Iterator<Entry<String, DownloadInfo>> iterator = set.iterator();
            while (iterator.hasNext()) {
                Entry<String, DownloadInfo> enter = iterator.next();
                DownloadInfo downloadInfo = enter.getValue();
                if (!downloadInfo.isFinishDownload()) {
                    downloadInfo.waitDownload();
                    DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
                    if (!downloadWaitQueue.contains(downloadInfo)) {
                        downloadWaitQueue.add(downloadInfo);
                        list.add(downloadInfo);
                    }
                }
            }
            CallbackObservable.getIntence().notifyObservers(CallbackEnum.WAIT_START_DOWNLOAD_LIST, list);
        }
    }

    private static List<HashMap.Entry<String, DownloadInfo>> listCollections(HashMap<String, DownloadInfo> canterMap) {
        List<HashMap.Entry<String, DownloadInfo>> list = new LinkedList<HashMap.Entry<String, DownloadInfo>>();
        list.addAll(canterMap.entrySet());
        Collections.sort(list, new Comparator<HashMap.Entry<String, DownloadInfo>>() {

            @Override
            public int compare(Entry<String, DownloadInfo> lhs, Entry<String, DownloadInfo> rhs) {
                DownloadInfo leftDownloadInfo = lhs.getValue();
                DownloadInfo rightDownloadInfo = rhs.getValue();
                if (leftDownloadInfo.getDownloadPriority() > rightDownloadInfo.getDownloadPriority()) {
                    return -1;
                } else if (leftDownloadInfo.getDownloadPriority() == rightDownloadInfo.getDownloadPriority()) {
                    if (leftDownloadInfo.getRequestStartTime() > rightDownloadInfo.getRequestStartTime()) {
                        return 1;
                    } else if (leftDownloadInfo.getRequestStartTime() == rightDownloadInfo.getRequestStartTime()) {
                        return 0;
                    } else {
                        return -1;
                    }
                } else {
                    return 1;
                }
            }
        });
        return list;
    }

    /**
     * 判断等待队列中是否有要加入的下载项，如有有。不添加
     * @param downloadWaitQueue
     * @param downloadInfo
     */
    private static long addDownloadWaitQueue(BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable, DownloadInfo downloadInfo) {
        if (!downloadWaitQueue.contains(downloadInfo) && !downloadInfoTable.contains(downloadInfo)) {
            downloadInfo.waitDownload();
            downloadWaitQueue.add(downloadInfo);
            return DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
        }
        return -1;
    }

    /**
     * 将任务删除等待队列
     * @param downloadWaitQueue
     * @param downloadInfo
     * @return
     */
    private static long deleteDownloadWaitQueue(BlockingQueue<DownloadInfo> downloadWaitQueue, DownloadInfo downloadInfo) {
        if (downloadWaitQueue.contains(downloadInfo)) {
            downloadWaitQueue.remove(downloadInfo);
            return DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
        }
        return -1;
    }

    /**
     * 启动线程队列的时候加载数据库
     * @param downloadWaitQueue
     */
    public static void initialize(BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable) {
        ControlCacheAndDb.downloadWaitQueue = downloadWaitQueue;
        ControlCacheAndDb.downloadInfoTable = downloadInfoTable;
        synchronized (DownloadSQLiteOpenHelper.class) {

            Iterator<Entry<String, DownloadInfo>> it = CacheDatabase.cloneCanterMap().entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, DownloadInfo> entry = it.next();
                DownloadInfo downloadInfo = (DownloadInfo) entry.getValue();
                if (downloadInfo.isStartDownload() || downloadInfo.isStopDownload() || downloadInfo.isWaitDownload()) {
                    addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                }
            }
        }
    }

    /***
     * 下载中更新或插入数据库   使用此方法的时候调用request.setAlreadyDownloadSize(count);更新request里面的下载大小，没写在这是为了锁分块，提高速度
     * @param request 如果返回0 为错误，需要处理。大于0为正确
     */
    public static long beginDownload(DownloadInfo myDownloadInfo) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            // 缓存更新 在调用的地方更新
            return DownloadFileDetailedHelper.beginDownload(myDownloadInfo);
        }
    }

    /**
     * 添加之前先将本地的删除后在下载
     * @param downloadInfo
     * @param downloadWaitQueue2
     * @param absDownloadInfoTable
     */
    public static void deleteAndAddDownloadItem(DownloadInfo downloadInfo,
            BlockingQueue<DownloadInfo> downloadWaitQueue2, Hashtable<String, DownloadInfo> DownloadInfoTable) {
        // TODO Auto-generated method stub
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(downloadInfo.getKey())) {
                deleteDownloadItem(downloadInfo, DownloadInfoTable);
                addDownloadItem(downloadInfo, downloadWaitQueue2, DownloadInfoTable);
            } else {
                addDownloadItem(downloadInfo, downloadWaitQueue2, DownloadInfoTable);
            }
        }
    }

    /**
     * 将数据保存到file_detailed数据库
     * @param request
     * @return
     */
    public static int addDownloadItem(DownloadInfo downloadInfo, BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (!map.containsKey(downloadInfo.getKey())) {
                CacheDatabase.getCanterMap().put(downloadInfo.getKey(), downloadInfo);
                long num = addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                if (num > 0) {
                    CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_ADD_DOWNLOAD_ITEM, downloadInfo);
                    isSilenceDownload(downloadInfoTable, downloadInfo);
                    return DownloadState.OPERATION_SUCCESS;
                }
                CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_FAILED,
                        CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
                return DownloadState.OPERATION_FAILED;
            } else {
                DownloadInfo myDownloadInfo = map.get(downloadInfo.getKey());
                if (myDownloadInfo.getDownloadPriority() < downloadInfo.getDownloadPriority()) {//如果是已经添加过得静默下载中。用户手动点击下载
                    myDownloadInfo.setDownloadPriority(DownloadInfo.DOWNLOAD_PRIORITY_10);
                    DownloadFileDetailedHelper.setFileDetailed(myDownloadInfo);
                }else if(myDownloadInfo.isDeleteDownload()){//添加判断，是否为sd卡文件丢失或者因为其他异常导致的文件下载错误
                    deleteDownloadItem(myDownloadInfo, downloadInfoTable);
                    addDownloadItem(myDownloadInfo, downloadWaitQueue, downloadInfoTable);
                    return DownloadState.OPERATION_SUCCESS;
                }else if(!myDownloadInfo.getDownloadFilePath().exists()){//如果sd卡下面文件丢失，删除数据库后重新下载
                    deleteDownloadItem(myDownloadInfo, downloadInfoTable);
                    addDownloadItem(myDownloadInfo, downloadWaitQueue, downloadInfoTable);
                    return DownloadState.OPERATION_SUCCESS;
                }
                CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_ALREADY_EXIST,
                        CallbackEnum.FAILED_DOWNLOAD, myDownloadInfo);
                return DownloadState.OPERATION_ALREADY_EXIST;
            }
        }
    }

    /**
     * 将数据保存到file_detailed数据库
     * @param request
     * @return
     */
    public static int addDownloadItem(DownloadInfo downloadInfo, boolean isSdEnableDownload,
            BlockingQueue<DownloadInfo> downloadWaitQueue, Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (isSdEnableDownload) {
                downloadInfo.enableDownload();
            } else {
                downloadInfo.unEnableDownload();
            }
            if (!map.containsKey(downloadInfo.getKey())) {
                CacheDatabase.getCanterMap().put(downloadInfo.getKey(), downloadInfo);
                long num = addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                if (num > 0) {
                    CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_ADD_DOWNLOAD_ITEM, downloadInfo);
                    isSilenceDownload(downloadInfoTable, downloadInfo);
                    return DownloadState.OPERATION_SUCCESS;
                }
                CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_FAILED,
                        CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
                return DownloadState.OPERATION_FAILED;
            } else {
                DownloadInfo myDownloadInfo = map.get(downloadInfo.getKey());
                if (myDownloadInfo.getDownloadPriority() < downloadInfo.getDownloadPriority()) {
                    myDownloadInfo.setDownloadPriority(DownloadInfo.DOWNLOAD_PRIORITY_10);
                    DownloadFileDetailedHelper.setFileDetailed(myDownloadInfo);
                }
                CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_ALREADY_EXIST,
                        CallbackEnum.FAILED_DOWNLOAD, myDownloadInfo);
                return DownloadState.OPERATION_ALREADY_EXIST;
            }
        }
    }

    /**
     * 将数据保存到file_detailed数据库
     * @param request
     * @return
     */
    public static void addDownloadList(List<? extends DownloadInfo> downloadInfoAddLists,
            BlockingQueue<DownloadInfo> downloadWaitQueue, Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            for (DownloadInfo downloadInfo : downloadInfoAddLists) {
                if (!map.containsKey(downloadInfo.getKey())) {
                    CacheDatabase.getCanterMap().put(downloadInfo.getKey(), downloadInfo);
                    long num = addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, downloadInfo);
                    if (num > 0) {
                        list.add(downloadInfo);
                        isSilenceDownload(downloadInfoTable, downloadInfo);
                    }
                    CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_FAILED,
                            CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
                } else {
                    DownloadInfo myDownloadInfo = map.get(downloadInfo.getKey());
                    if (myDownloadInfo.getDownloadPriority() < downloadInfo.getDownloadPriority()) {
                        myDownloadInfo.setDownloadPriority(DownloadInfo.DOWNLOAD_PRIORITY_10);
                        DownloadFileDetailedHelper.setFileDetailed(myDownloadInfo);
                    }
                    CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_ALREADY_EXIST,
                            CallbackEnum.FAILED_DOWNLOAD, myDownloadInfo);
                }
            }
            Collections.sort(list, new DownloadInfoComparatorUtils());
            CallbackObservable.getIntence().notifyObservers(CallbackEnum.ADD_DOWNLOAD_LIST, list);
        }
    }

    /**
     * 是否是静默下载，如果是暂停静默下载，线程中暂停同时在加入到等待队列中
     * @param downloadInfoTable
     * @param downloadInfo
     */
    private static void isSilenceDownload(Hashtable<String, DownloadInfo> downloadInfoTable, DownloadInfo downloadInfo) {
        if (downloadInfo.getDownloadPriority() == DownloadInfo.DOWNLOAD_PRIORITY_5) {
            return;
        }
        Iterator<Entry<String, DownloadInfo>> hashtableDownloads = downloadInfoTable.entrySet().iterator();
        while (hashtableDownloads.hasNext()) {
            Entry<String, DownloadInfo> entry = hashtableDownloads.next();
            DownloadInfo hashtableDownload = entry.getValue();
            if (hashtableDownload.getDownloadPriority() == DownloadInfo.DOWNLOAD_PRIORITY_5) {
                hashtableDownloads.remove();
                hashtableDownload.pauseSilenceDownload();
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WILL_PAUSE_DOWNLOAD_ITEM,
                        hashtableDownload);
                return;
            }
        }
    }

    /**
     * 获取下一条下载项
     */
    private static void getNextDownloadInfo(BlockingQueue<DownloadInfo> downloadWaitQueue) {
        DownloadInfo headDownloadInfo = downloadWaitQueue.peek();
        if (headDownloadInfo != null) {
            CallbackObservable.getIntence().notifyObservers(CallbackEnum.GET_NEXT_DOWNLOAD_INFO, headDownloadInfo);
        }

    }

    /**
     * 下载暂停  因为重新启动后，暂停的下载内容也进入下载队列。所以不更新数据库，只更新缓存,同时删除等待队列的对象
     * @param key
     * @return
     */
    public static int pauseDownloadItem(DownloadInfo downloadInfo, BlockingQueue<DownloadInfo> downloadWaitQueue) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(key)) {
                DownloadInfo myDownloadInfo = map.get(key);
                if (!myDownloadInfo.isPauseDownload()) {
                    myDownloadInfo.pauseDownload();
                    deleteDownloadWaitQueue(downloadWaitQueue, myDownloadInfo);
                    getNextDownloadInfo(downloadWaitQueue);
                    CallbackObservable.getIntence()
                            .notifyObservers(CallbackEnum.WILL_PAUSE_DOWNLOAD_ITEM, downloadInfo);
                    return DownloadState.OPERATION_SUCCESS;
                } else {
                    CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_ALREADY_EXIST,
                            CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
                    return DownloadState.OPERATION_ALREADY_EXIST;
                }
            }
            CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_FAILED,
                    CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
            return DownloadState.OPERATION_FAILED;
        }
    }

    /**
     * 下载停止  因为重新启动后，暂停的下载内容也进入下载队列。所以不更新数据库，只更新缓存
     * @param key
     * @return
     */
    public static int stopDownloadingItem(DownloadInfo downloadInfo) {
        DownloadLog.debug("stopDownloadingTask：begin  synchronized before");
        synchronized (DownloadSQLiteOpenHelper.class) {
            DownloadLog.debug("stopDownloadingTask：begin  synchronized later");
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(key)) {
                DownloadLog.debug("stopDownloadingTask：begin  containsKey later");
                DownloadInfo myDownloadInfo = map.get(key);
                if (!myDownloadInfo.isStopDownload()) {
                    myDownloadInfo.stopDownload();
                    deleteDownloadWaitQueue(downloadWaitQueue, myDownloadInfo);
                    getNextDownloadInfo(downloadWaitQueue);
                    return DownloadState.OPERATION_SUCCESS;
                } else {
                    return DownloadState.OPERATION_ALREADY_EXIST;
                }
            }
            return DownloadState.OPERATION_FAILED;
        }
    }

    /**
     * 删除下载   用户点击调用
     * @param downloadInfo
     * @return
     */
    public static int deleteDownloadItem(DownloadInfo downloadInfo, Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(key)) {
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WILL_DELETE_DOWNLOAD_ITEM, downloadInfo);
                DownloadInfo mDownloadInfo = map.get(key);
                mDownloadInfo.deleteDownload();
                getNextDownloadInfo(downloadWaitQueue);
                DownloadFileDetailedHelper.setFileDetailed(mDownloadInfo);
                map.remove(key);
                if (downloadInfoTable.contains(mDownloadInfo)) {
                    // 设置正在下载的为取消状态
                    mDownloadInfo.setCanceled(true);
                } else {
                    // 删除下载队列中的条目
                    deleteDownloadWaitQueue(downloadWaitQueue, mDownloadInfo);
                }
                DownloadFilePathUtils.deleteFile(mDownloadInfo.getDownloadFilePath());
                int num = DownloadFileDetailedHelper.deleteDownloadItem(mDownloadInfo);
                if (num > 0) {
                    CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_DELETE_DOWNLOAD_ITEM,
                            downloadInfo);
                    return DownloadState.OPERATION_SUCCESS;
                } else {
                    CallbackObservable.getIntence().notifyObservers(DownloadState.DATABASE_ERROR_DELETE_FILE,
                            CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
                    return DownloadState.DATABASE_ERROR_DELETE_FILE;
                }

            }
            return DownloadState.OPERATION_FAILED;
        }
    }

    /**
     * 删除下载   用户点击调用
     * @param downloadInfo
     * @return
     */
    public static void deleteDownloadList(List<? extends DownloadInfo> downloadInfoDeleteLists,
            Hashtable<String, DownloadInfo> DownloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            ArrayList<DownloadInfo> listSuccess = new ArrayList<DownloadInfo>();
            for (DownloadInfo downloadInfo : downloadInfoDeleteLists) {
                String key = downloadInfo.getKey();
                HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
                if (map.containsKey(key)) {
                    CallbackObservable.getIntence().notifyObservers(CallbackEnum.WILL_DELETE_DOWNLOAD_ITEM,
                            downloadInfo);
                    DownloadInfo mDownloadInfo = map.get(key);
                    mDownloadInfo.deleteDownload();
                    getNextDownloadInfo(downloadWaitQueue);
                    DownloadFileDetailedHelper.setFileDetailed(mDownloadInfo);
                    if (DownloadInfoTable.contains(mDownloadInfo)) {
                        // 在线程内处理，最后调用下面deleteDownloadItemInThread方法
                    } else {
                        map.remove(key);
                        deleteDownloadWaitQueue(downloadWaitQueue, mDownloadInfo);
                        DownloadFilePathUtils.deleteFile(mDownloadInfo.getDownloadFilePath());
                        int num = DownloadFileDetailedHelper.deleteDownloadItem(mDownloadInfo);
                        if (num > 0) {
                            listSuccess.add(mDownloadInfo);
                        } else {
                            CallbackObservable.getIntence().notifyObservers(DownloadState.DATABASE_ERROR_DELETE_FILE,
                                    CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
                        }

                    }
                }
            }
            CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_DELETE_DOWNLOAD_LIST, listSuccess);
        }
    }

    /**
     * 删除下载  下载中线程调用
     * @param downloadInfo
     * @return
     */
    public static int deleteDownloadItemInThread(DownloadInfo downloadInfo) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsValue(downloadInfo)) {
                // CallbackObservable.getIntence().notifyObservers(CallbackEnum.WILL_DELETE_DOWNLOAD_ITEM,
                // downloadInfo);
                DownloadInfo mDownloadInfo = map.get(key);
                if (mDownloadInfo.isDeleteDownload()) {
                    DownloadFileDetailedHelper.deleteDownloadItem(mDownloadInfo);
                    map.remove(key);
                    CallbackObservable.getIntence()
                            .notifyObservers(CallbackEnum.DID_DELETE_DOWNLOAD_ITEM, downloadInfo);
                }
            }
            return DownloadState.OPERATION_FAILED;
        }
    }

    /**
     * 有本地文件没有数据库
     * @param downloadInfo
     */
    public static void deleteDownloadFile(DownloadInfo downloadInfo) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsValue(downloadInfo)) {
                map.remove(downloadInfo);
            }
            CallbackObservable.getIntence().notifyObservers(DownloadState.DATABASE_ERROR_NO,
                    CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
        }
    }

    /**
     * 只有数据库没有sd卡文件
     */
    public static void deleteDownloadMapItem(DownloadInfo downloadInfo) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsValue(downloadInfo)) {
                map.remove(downloadInfo);
            }
            CallbackObservable.getIntence().notifyObservers(DownloadState.DATABASE_ERROR_NO_FILE,
                    CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
        }
    }

    /**
     * 恢复下载
     * @param key
     * @return
     */
    public static int startDownloadItem(DownloadInfo downloadInfo, BlockingQueue<DownloadInfo> downloadWaitQueue,
            Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(key)) {
                DownloadInfo myDownloadInfo = map.get(key);
                if (myDownloadInfo.isFinishDownload()) {
                    return DownloadState.OPERATION_SUCCESSED;
                }
                addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, myDownloadInfo);
                isSilenceDownload(downloadInfoTable, myDownloadInfo);
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WAIT_START_DOWNLOAD_ITEM, myDownloadInfo);
                return DownloadState.OPERATION_SUCCESS;
            } else {
                // TODO 如果不存在 添加进去
            }
            CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_FAILED,
                    CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
            return DownloadState.OPERATION_FAILED;
        }
    }

    /**
     * SD卡空间不足时暂停，恢复下载
     * @param key
     * @return
     */
    public static int startDownloadItem(DownloadInfo downloadInfo, boolean isSdEnableDownload,
            BlockingQueue<DownloadInfo> downloadWaitQueue, Hashtable<String, DownloadInfo> downloadInfoTable) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(key)) {
                DownloadInfo myDownloadInfo = map.get(key);
                if (myDownloadInfo.isFinishDownload()) {
                    return DownloadState.OPERATION_SUCCESSED;
                }
                if (isSdEnableDownload) {
                    myDownloadInfo.enableDownload();
                } else {
                    myDownloadInfo.unEnableDownload();
                }
                addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, myDownloadInfo);
                isSilenceDownload(downloadInfoTable, myDownloadInfo);
                CallbackObservable.getIntence().notifyObservers(CallbackEnum.WAIT_START_DOWNLOAD_ITEM, myDownloadInfo);
                return DownloadState.OPERATION_SUCCESS;
            } else {
                // TODO 如果不存在 添加进去
            }
            CallbackObservable.getIntence().notifyObservers(DownloadState.OPERATION_FAILED,
                    CallbackEnum.FAILED_DOWNLOAD, downloadInfo);
            return DownloadState.OPERATION_FAILED;
        }
    }

    /**
     * 恢复静默下载。加入到等待队列
     * @return
     */
    public static void startSilenceDownloadItem(DownloadInfo downloadInfo) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            String key = downloadInfo.getKey();
            HashMap<String, DownloadInfo> map = CacheDatabase.getCanterMap();
            if (map.containsKey(key)) {
                DownloadInfo apkDownloadModel = map.get(key);
                if (apkDownloadModel.isSilenceDownloadPause()) {
                    apkDownloadModel.unPauseSilenceDownload();
                }
                addDownloadWaitQueue(downloadWaitQueue, downloadInfoTable, apkDownloadModel);
            }
        }
    }

    public static void pauseAllDownloadingTasks(BlockingQueue<DownloadInfo> downloadWaitQueue) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            // 先清队列在清缓存，防止联网请求
            // downloadWaitQueue.removeAll(); TODO 写排序算法，清除下载队列
            // CacheDatabase.pauseAllDownloading();
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            Iterator<Entry<String, DownloadInfo>> it = CacheDatabase.getCanterMap().entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, DownloadInfo> entry = it.next();
                DownloadInfo downloadInfo = entry.getValue();
                if (downloadInfo.isStartDownload() || downloadInfo.isWaitDownload()) {
                    downloadInfo.pauseDownload();
                    deleteDownloadWaitQueue(downloadWaitQueue, downloadInfo);
                    DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
                    list.add(downloadInfo);
                }
            }
            CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_PAUSE_DOWNLOAD_LIST, list);

        }
    }

    public static void stopAllDownloadingTasks(BlockingQueue<DownloadInfo> downloadWaitQueue) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            // 先清队列在清缓存，防止联网请求
            // downloadWaitQueue.removeAll(); TODO 写排序算法，清除下载队列
            // CacheDatabase.pauseAllDownloading();
            ArrayList<DownloadInfo> list = new ArrayList<DownloadInfo>();
            Iterator<Entry<String, DownloadInfo>> it = CacheDatabase.getCanterMap().entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, DownloadInfo> entry = it.next();
                DownloadInfo downloadInfo = entry.getValue();
                if (downloadInfo.isStartDownload() || downloadInfo.isWaitDownload()) {
                    downloadInfo.stopDownload();
                    deleteDownloadWaitQueue(downloadWaitQueue, downloadInfo);
                    DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
                    list.add(downloadInfo);
                }
            }
            CallbackObservable.getIntence().notifyObservers(CallbackEnum.DID_STOP_DOWNLOAD_LIST, list);

        }
    }

    /**
     * 更新FileDetailed表
     * @param downloadInfo
     */
    private static void setFileDetailed(DownloadInfo downloadInfo) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
        }
    }

    public static void keepNowStateStopAllTasks(BlockingQueue<DownloadInfo> downloadWaitQueue) {
        synchronized (DownloadSQLiteOpenHelper.class) {
            HashMap<String, DownloadInfo> canterMap = CacheDatabase.getCanterMap();
            if (canterMap.size() > 0) {
                Iterator<Entry<String, DownloadInfo>> iterator = canterMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Entry<String, DownloadInfo> entry = iterator.next();
                    DownloadInfo downloadInfo = entry.getValue();
                    iterator.remove();
                    DownloadFileDetailedHelper.setFileDetailed(downloadInfo);
                }
            }
        }
    }

}
